package CIF::Archive::DataType::Plugin::Malware;
use base 'CIF::Archive::DataType';

use strict;
use warnings;

use Module::Pluggable require => 1, search_path => [__PACKAGE__], except => qr/SUPER$/;
use DateTime;

__PACKAGE__->table('malware');
__PACKAGE__->columns(Primary => 'id');
__PACKAGE__->columns(All => qw/id uuid guid source sha1 md5 confidence severity restriction detecttime created/);
__PACKAGE__->columns(Essential => qw/id uuid guid source sha1 md5 confidence severity restriction detecttime created/);
__PACKAGE__->sequence('malware_id_seq');

my @plugins = __PACKAGE__->plugins();

## sub lookup is handled by Plugin::Hash (you should have that installed)
sub lookup { return; }

sub prepare {
    my $class = shift;
    my $info = shift;

    return unless($info->{'impact'} && $info->{'impact'} eq 'malware');
    my $hash = $info->{'sha1'} || $info->{'md5'} || return(undef);
    $hash = lc($hash);
    return unless($hash =~ /^[a-f0-9]{32,40}$/);

    return(1);
}

sub insert {
    my $self = shift;
    my $info = shift;
   
    my $t = $self->table();
    foreach(@plugins){
        if($_->prepare($info)){
            $self->table($_->table());
        }
    }

    my $id = eval { $self->SUPER::insert({
        uuid        => $info->{'uuid'},
        source      => $info->{'source'},
        md5         => $info->{'md5'},
        sha1        => $info->{'sha1'},
        confidence  => $info->{'confidence'},
        severity    => $info->{'severity'} || 'null',
        restriction => $info->{'restriction'} || 'private',
        detecttime  => $info->{'detecttime'},
        guid        => $info->{'guid'},
        created     => $info->{'created'} || DateTime->from_epoch(epoch => time()),
    }) };
    if($@){
        return($@,undef) unless($@ =~ /duplicate key value violates unique constraint/);
    }
    $self->table($t);
}

sub feed {
    my $class = shift;
    my $info = shift;

    my @feeds;
    $info->{'key'} = 'md5';
    my $ret = $class->_feed($info);
    return unless($ret);
    push(@feeds,$ret) if($ret);

    foreach(@plugins){
        my $r = $_->_feed($info);
        push(@feeds,$r) if($r);
    }
    return(\@feeds);
}

__PACKAGE__->set_sql('feed' => qq{
    SELECT DISTINCT on (__TABLE__.md5) __TABLE__.md5, sha1, confidence, archive.uuid, archive.data
    FROM __TABLE__
    LEFT JOIN apikeys_groups ON __TABLE__.guid = apikeys_groups.guid
    LEFT JOIN archive ON __TABLE__.uuid = archive.uuid
    WHERE
        detecttime >= ?
        AND __TABLE__.confidence >= ?
        AND severity >= ?
        AND __TABLE__.restriction <= ?
        AND apikeys_groups.uuid = ?
    ORDER BY __TABLE__.md5 ASC, __TABLE__.id ASC, confidence DESC, severity DESC, __TABLE__.restriction ASC
    LIMIT ?
});

1;
__END__

=head1 NAME

 CIF::Archive::DataType::Plugin::Malware - CIF::Archive plugin for indexing malware

=head1 SEE ALSO

 http://code.google.com/p/collective-intelligence-framework/
 CIF::Archive

=head1 AUTHOR

 Wes Young, E<lt>wes@barely3am.comE<gt>

=head1 COPYRIGHT AND LICENSE

 Copyright (C) 2011 by Wes Young (claimid.com/wesyoung)
 Copyright (C) 2011 by the Trustee's of Indiana University (www.iu.edu)
 Copyright (C) 2011 by the REN-ISAC (www.ren-isac.net)

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.10.0 or,
at your option, any later version of Perl 5 you may have available.

=cut
